package jm.easyconfig;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;

abstract public class ConfigUpdater {

	static public ConfigUpdater startup(MySqlConfigSource configSource, CfgContextEnvironmentAware ctxAware)
			throws Throwable {

		Environment env = CfgContextEnvironmentAware.environment;
		String clazz = env.getProperty(SysProps.UPDATER, "auto");

		if ("auto".equals(clazz)) {
			if (env.containsProperty("easyconfig.rabbitmq.addresses")
					|| env.containsProperty("spring.rabbitmq.addresses")) {

				clazz = "rabbitmq";

			} else if (ClassUtils.isPresent("org.springframework.amqp.rabbit.connection.AbstractConnectionFactory",
					ConfigUpdater.class.getClassLoader())) {

				String[] names = CfgContextEnvironmentAware.applicationContext
						.getBeanNamesForType(AbstractConnectionFactory.class, false, false);

				clazz = names.length > 0 ? "rabbitmq" : "polling";

				if (names.length > 1) {
					CfgHelper.logger.warn(
							"failed to get AbstractConnectionFactory from spring because more than one[{}] exists.",
							names.length);
				}

			} else
				clazz = "polling";

		}

		if ("polling".equals(clazz)) {

			clazz = jm.easyconfig.PollingUpdater.class.getName();

		} else if ("rabbitmq".equals(clazz)) {

			clazz = jm.easyconfig.RabbitmqUpdater.class.getName();

		} else {
			CfgHelper.logger.error("Wrong value[{}] of property {}.", clazz, SysProps.UPDATER);
		}

		ConfigUpdater publisher = (ConfigUpdater) Class.forName(clazz).newInstance();

		publisher.init(configSource, ctxAware);

		ctxAware.register(publisher);

		return publisher;
	}

	@PostConstruct
	public void init(MySqlConfigSource configSource, CfgContextEnvironmentAware ctxAware) {
	}

	abstract public void publish(List<ConfigItemCore> updatedResult, List<String> nodeList);

	@PreDestroy
	public void close() {

	}
}
